package com.ibr.ticketmanagement.app;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import com.ibr.ticketmanagement.app.data.FEReport;
import com.ibr.ticketmanagement.app.data.Location;
import com.ibr.ticketmanagement.app.data.Part;
import com.ibr.ticketmanagement.app.util.Utility;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.List;

/**
 * An {@link IntentService} subclass for handling asynchronous task requests in
 * a service on a separate handler thread.
 * <p/>
 * TODO: Customize class - update intent actions, extra parameters and static
 * helper methods.
 */
public class DatabaseService extends IntentService {

    // TODO: Rename actions, choose action names that describe tasks that this
    // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
    public static final String ACTION_SYNC_DATABASE = "com.ibr.ticketmanagement.app.SplashScreen";
    public static final String ACTION_SUBMIT_FE_REPORT = "com.ibr.ticketmanagement.app.FEReportActivity";
    private final String TAG = "DATABASE_SERVICE";
//    private static final String ACTION_BAZ = "com.ibr.ticketmanagement.app.action.BAZ";

    // TODO: Rename parameters
//    private static final String EXTRA_PARAM1 = "com.ibr.ticketmanagement.app.extra.PARAM1";
//    private static final String EXTRA_PARAM2 = "com.ibr.ticketmanagement.app.extra.PARAM2";

    public DatabaseService() {
        super("DatabaseService");
    }


    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent != null) {
            final String action = intent.getAction();
            if (ACTION_SYNC_DATABASE.equals(action)) {
                startActionSyncDatabase();
            }
            if (ACTION_SUBMIT_FE_REPORT.equals(action)) {
                // TODO: check if more action plans are required to be loaded from server.
                postFEReportsToServer();
            }
        }
    }

    private void postFEReportsToServer() {
        //check the network available
        ConnectivityManager connMgr = (ConnectivityManager)
                this.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            List<FEReport> listFeReport = Utility.getFeReportsToBeSubmitted(this);
            for (int i = 0; i < listFeReport.size(); i++) {
                Utility.postFeReport(this, listFeReport.get(i));
            }
        }
    }

    /**
     * Handle action Foo in the provided background thread with the provided
     * parameters.
     */
    private void startActionSyncDatabase() {
        //check the network available
        ConnectivityManager connMgr = (ConnectivityManager)
                this.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            long timeStart = System.currentTimeMillis();
            Log.i(TAG, "$$$$$$$$$$$$$$ Starting Location and Part Sync Call $$$$$$$$$$$$$$$$");
            // make the network call
            //save in sql db
            Log.i(TAG, "Will make location call");
            JSONObject locCollection = Utility.downloadJsonFromURI(Utility.FETCH_LOCATIONS_URL, true);
            Log.i(TAG, "Location found :" + locCollection.toString());
            if (locCollection != null) {
                Utility.getNextLocationVersion(this);
                //Fetch Location
                try {
                    JSONArray locArray = locCollection.getJSONArray("wrapper");
                    String[] locations = new String[locArray.length() + 1];
                    locations[0] = "Select Location";
                    for (int i = 0; i < locArray.length(); i++) {
                        try {
                            JSONObject locationJSOn = locArray.getJSONObject(i);
                            Log.i(TAG, "Got Json object for location:" + locationJSOn.toString());
                            Location location =
                                    new Location(String.valueOf(locationJSOn.getInt("id")), locationJSOn.getString("name"),
                                            Utility.getLocationVersion(this));
                            Log.i(TAG, "Created a location");
                            Utility.saveLocation(this, location);
                            Log.i(TAG, "Location Saved");
                            locations[i + 1] = location.getLocation();
                        } catch (Exception e) {
                            Log.e(TAG, "Not able to get single Location Json", e.fillInStackTrace());
                        }
                    }
                    Utility.setLocation(this, locations);
                } catch (Exception e) {
                    Log.e(TAG, "Not able to get Location Json", e.fillInStackTrace());
                }
            }
            Log.i(TAG, "Will make part call");
            JSONObject partCollection = Utility.downloadJsonFromURI(Utility.FETCH_PARTS_URL, true);
            if (partCollection != null) {
                // Fetch Part
                try {
                    JSONArray partArray = partCollection.getJSONArray("wrapper");
                    String[] parts = new String[partArray.length() + 1];
                    parts[0] = "Select Part";
                    for (int i = 0; i < partArray.length(); i++) {
                        try {
                            JSONObject partJSOn = partArray.getJSONObject(i);
                            Log.i(TAG, "Got Json part:" + partJSOn.toString());
                            Part part =
                                    new Part(partJSOn.getString("id"), partJSOn.getString("part_number"));
                            if (part == null || part.getPartId() == null || "0".equals(part.getPartId()) || part.getPart() == null) {
                                Log.i(TAG, "Part values are null. ignoring the Part");
                                continue;
                            }
                            Log.i(TAG, "Created a part object");
                            JSONObject locationJSOn = partJSOn.getJSONObject("location");
                            Log.i(TAG, "Created a location Json " + locationJSOn.toString());
                            long locationId = (locationJSOn != null) ? Utility.saveLocation(this, new Location(String.valueOf(locationJSOn.getInt("id")),
                                    locationJSOn.getString("name"), Utility.getLocationVersion(this))) : 0;
                            Log.i(TAG, "Got location id:" + locationId);
                            Utility.savePart(this, part, locationId, partJSOn.getInt("quantity"));
                            Log.i(TAG, "part saved");
                            parts[i + 1] = part.getPart();
                        } catch (Exception e) {
                            Log.e(TAG, "Not able to get single Part Json", e.fillInStackTrace());
                        }
                    }
                    Utility.setPart(this, parts);
                } catch (Exception e) {
                    Log.e(TAG, "Not able to get Part Json", e.fillInStackTrace());
                }
            }
            Log.i(TAG, "$$$$$$$$$$$$$$ END of Location and Part Sync Call $$$$$$$$$$$$$$$$ TOTAL TIME:" + (System.currentTimeMillis() - timeStart) + "mills");
            //TODO: clean up the DB to remove old location and location part mapping and part which are not used in mapping.
        }
    }
}